#include "Socket.hpp"
#define DFL -1
int fdsArray[sizeof(fd_set) * 8] = {0};
int gnum = sizeof(fdsArray) / sizeof(fdsArray[0]);

static void showArray()
{
    cout << "当前托管的fd:" << endl;
    for (int i = 0; i < gnum; i++)
    {
        if (fdsArray[i] != DFL)
            cout << fdsArray[i] << " ";
    }
    cout << endl;
}
static void HandlerEvent(int listensock, fd_set &readfds)
{
    for (int i = 0; i < gnum; i++)
    {
        if (i == 0 && FD_ISSET(listensock, &readfds))
        {
            cout << "已有新的连接到来了，需要获取！" << endl;
            uint16_t peerPort;
            string ip;
            int sockfd = Sock::Accept(listensock, &peerPort, &ip);
            int k = 0;
            while (fdsArray[k] != DFL)
                ++k;
            if (k == gnum)
            {
                cout << "服务器已经达到了最大的上限了，无法保持更多连接了" << endl;
                close(sockfd);
            }
            else
            {
                fdsArray[k] = sockfd;
                showArray();
            }
        }
        else if (FD_ISSET(fdsArray[i], &readfds))
        {
            char buffer[1024];
            ssize_t s = recv(fdsArray[i], buffer, sizeof(buffer), 0);
            if (s <= 0)
            {
                cout << "client closed or read error,server close" << fdsArray[i] << endl;
                close(fdsArray[i]);
                fdsArray[i] = DFL;
                ;
                showArray();
            }
            else
            {
                buffer[s] = 0;
                cout << "client[" << fdsArray[i] << "]#" << buffer << endl;
            }
        }
    }
}
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Usage:\n\t" << argv[0] << " port" << endl;
        exit(-1);
    }
    int listenSock = Sock::Socket();
    Sock::Bind(listenSock, atoi(argv[1]));
    Sock::Listen(listenSock);
    for (int i = 0; i < gnum; i++)
        fdsArray[i] = DFL;
    fdsArray[0] = listenSock;
    while (1)
    {
        int maxfd = DFL;
        fd_set readfds;
        FD_ZERO(&readfds);
        for (int i = 0; i < gnum; i++)
        {
            if (fdsArray[i] == DFL)
                continue;
            FD_SET(fdsArray[i], &readfds);
            if (maxfd < fdsArray[i])
                maxfd = fdsArray[i];
        }
        timeval timeout = {5, 0};
        int n = select(maxfd + 1, &readfds, nullptr, nullptr, &timeout);
        switch (n)
        {
        case 0:
            cout << "time out..." << time(nullptr) << endl;
            break;
        case -1:
            cerr << errno << strerror(errno) << endl;
            break;
        default:
            HandlerEvent(listenSock, readfds);
            break;
        }
    }
    return 0;
}